# @Time : 2020/7/17 15:48
# @Author : Fioman 
# @Phone : 13149920693
"""
数字水印:
最低有效位(Least Significant Bit, LSB)指的是一个二进制数中的第0位(即最低有效位.)
最低有效位信息隐藏指的是,将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位,即将载体图像的最低有效位层替换为当前需要隐藏的二值图像,
从而实现将二值图像隐藏的目的.
有必要的时候,直接将载体图像的最低有效位层提取出来,即可得到嵌入在该位上的二值图像,达到提取秘密信息的目的.
这种信息隐藏也被称为数字水印,通过该方式可以实现信息隐藏,版权认证,身份认证等功能.例如,如果嵌入载体图像内的信息是秘密信息,就实现了信息隐藏;
如果嵌入载体图像内的信息是身份信息,就可以实现数字签名,等等.

原理:
从位平面的角度考虑,数字水印的处理过程分为下面两步:
嵌入过程:将载体图像的第0个位平面替换为数字水印信息(一幅二值图像)
提取过程:将载体图像的最低有效位所构成的第0个位平面提取出来,得到数字水印信息.
"""

import cv2 as cv
import numpy as np
waterMark = cv.imread("waterMark.png",cv.IMREAD_GRAYSCALE)
lena = cv.imread("lena.bmp",cv.IMREAD_GRAYSCALE)
lena = cv.resize(lena,(waterMark.shape[1],waterMark.shape[0]))
r,c = lena.shape

# 将水印图像内的值255处理为1,以方便嵌入.
w = waterMark[:,:] > 0
waterMark[w] = 1

# 嵌入过程
# 生成元素值都是254的数组
t254 = np.ones((r,c),dtype=np.uint8)*254

# 获取lena图像的高7位
lenaH7 = cv.bitwise_and(lena,t254)
# 将waterMark嵌入到lenaH7内
print("lenaH7.shape = {},waterMark.shape = {}".format(lenaH7.shape,waterMark.shape))
e = cv.bitwise_or(lenaH7,waterMark)

# 提取过程,生成元素值都是1的数组
t1 = np.ones((r,c),dtype=np.uint8)
# 从载体图像内提取水印图像
wm = cv.bitwise_and(e,t1)
print(wm)

# 将水印图像内的值1处理为255,以方便显示
w = wm[:,:] > 0
wm[w] = 255

# 显示
cv.imshow("lena",lena)
cv.imshow("waterMark",waterMark*255)
cv.imshow("e",e)
cv.imshow("wm",wm)
cv.waitKey(0)
cv.destroyAllWindows()
















